new Vue({
    el: '#app',
    data() {
        return {
            blacklist: ['V_FieldsName'],//黑名单
            form: {
                SQL_SerialNumber: '',//标识
                SQL_Name: '',//名称
                SQL_Statement: '',//sql字符串
                SQL_Type: '0',//类型 0：默认配置 1：自定义配置
                Line_JSON: '',//连线
                Box_JSON: '',//盒子
                Model_Number: '',//关联菜单
                Condition: '',//条件
                Order: '',//排序
                Distinct: '0',
            },
            rules: [],
            table: [],//全部表
            tableName: '',//主表表名
            tableData: [],//主表全部字段
            condition: [],//条件
            order: [],//排序
            columnType: {
                "0": "文本",
                "1": "图片"
            },
            subTable: [],//关联表
            selecteTable: [],//选中表
            showTable: [],//sql预览查询
            isShow: true,
            isTabs: true,
            SQL: '',//自定义SQL
            Join: [{//连接方式
                label: '左连接',
                value: 'LEFT JOIN'
            }, {
                label: '右连接',
                value: 'RIGHT JOIN'
            }, {
                label: '内连接',
                value: 'INNER JOIN'
            }],//连接方式
            jsPlumbInstance: "", //jsPlumb实例
            jsPlumbSetting: {
                // 动态锚点、位置自适应
                Anchors: ['Top', 'TopCenter', 'TopRight', 'TopLeft', 'Right', 'RightMiddle', 'Bottom', 'BottomCenter', 'BottomRight', 'BottomLeft', 'Left', 'LeftMiddle'],
                // 连线的样式 StateMachine、Flowchart，Bezier、Straight
                Connector: ['StateMachine', { curviness: 60 }],
                // 鼠标是否拖动删除线
                ConnectionsDetachable: false,
                // 删除线的时候节点不删除
                DeleteEndpointsOnDetach: false,
                // 连线的两端端点类型：矩形 Rectangle；圆形Dot； eight: 矩形的高 ，idth: 矩形的宽
                Endpoints: [['Dot', { radius: 2, }], ['Dot', { radius: 2 }]],
                // 线端点的样式
                EndpointStyle: { fill: '#67C23A', outlineWidth: 1, radius: 5 },
                // 绘制连线
                PaintStyle: {
                    stroke: '#67C23A',
                    strokeWidth: 1,
                    outlineStroke: 'transparent',
                    // 设定线外边的宽，单位px
                    outlineWidth: 10
                },
                // 绘制连线箭头
                Overlays: [// 箭头叠加
                    ['Arrow', {
                        width: 10, // 箭头尾部的宽度
                        length: 8, // 从箭头的尾部到头部的距离
                        location: 1, // 位置，建议使用0～1之间
                        direction: 1, // 方向，默认值为1（表示向前），可选-1（表示向后）
                        foldback: 0.623 // 折回，也就是尾翼的角度，默认0.623，当为1时，为正三角
                    }]
                ],
                // 绘制图的模式 svg、canvas
                RenderMode: 'svg',
                DragOptions: { cursor: 'pointer', zIndex: 2000 },
                // 鼠标滑过线的样式
                HoverPaintStyle: { stroke: '#F56C6C', strokeWidth: 1, cursor: 'pointer' },
            },
            // 连线的配置
            jsPlumbConnectOptions: {
                isSource: true,
                isTarget: true,
                // 动态锚点、提供了4个方向 Continuous、AutoDefault
                anchor: "Continuous",
                overlays: [['Arrow', { width: 8, length: 8, location: 1 }]] // overlay
            },
            commonLink: {
                isSource: true,
                isTarget: true,
                anchor: ["Perimeter", { shape: "Circle" }],
                connector: ['StateMachine'],//Bezier贝塞尔曲线，Flowchart流程图连接线， StateMachine曲线， Straight直线
                endpoint: 'Dot',//设置为点
                maxConnections: -1,// 不限制节点的连线数量,
            },
            nodeList: [],
            lineList: [],//连接线
            Box_JSON: {},
            selectLine: {},//选中连接线
            role: {},
            dialogVisible: false,//点击连接线弹窗
            dialogVisible2: false,//点击回收站弹窗
            loading: false,//节流
            Sortable: null,//拖拽类
            isSort: false,//是否启动拖拽
            isError: false,//是否有误
            isModify: true,
            isfirst: true,
            isTable: true,
            Error_Explain: '暂未查询到数据',
            allTableData: [],
            recycle: [],//回收站
            action: 'Add',
            nodeKey: '',
            referrer: '',//上个页面
            tableNumber: 0,
            actualNumber: 0,
        }
    },
    computed: {
        location() {
            return function (str) {
                if (this.Box_JSON[str]) {
                    const { left, top } = this.Box_JSON[str]
                    return { left: left + 'px', top: top + 'px' };
                } else {
                    return str == this.tableName ? { left: '10px', top: '10px' } : { right: '20px', top: '10px' };
                }
            }
        },
        tableNames() {
            if (this.form.SQL_Type == '0') {
                return [...this.tableData, ...this.configTable(this.tableName)];
            } else if (this.form.SQL_Type == '1') {
                let tableNames = [];
                try {
                    const regex = /IFNULL\(\s*([^,]+?)\s*,\s*'[^']*'\s*\)/gi;//去掉IFNULL函数及其数据
                    let SQL = this.SQL.replaceAll('`', '').replace(regex, '$1').replace(/DATE_FORMAT\(\s*([^,]+?)\s*,\s*'[^']*'\s*\)/gi, '$1');
                    let index = SQL.toUpperCase().indexOf('FROM');
                    if (index !== -1) {
                        SQL.substring(0, index).split(',').forEach((str, num) => {
                            if (num == 0) {
                                str = str.replace(/^SELECT\s+(?:DISTINCT\s+)?/i, '');
                            }
                            let arr = str.replaceAll('\r', '').replaceAll('\n', '').split('.');
                            let TABLE_NAME = arr[0].trim(), COLUMN_NAME = arr[1].trim(), NickName = arr[1].trim();
                            if (/ as /gi.test(COLUMN_NAME)) {
                                let strArr = COLUMN_NAME.split(/ as /gi);
                                COLUMN_NAME = strArr[0].trim(), NickName = strArr[1].trim();
                            }
                            tableNames.push({
                                COLUMN_COMMENT: '',
                                COLUMN_NAME,
                                NickName,
                                TABLE_NAME,
                                isShow: true,
                                Column_Width: '180',
                                Column_Type: '0',
                                Show_Overflow_Tooltip: true,
                                Column_Align: 'left',
                                Role: ''
                            })
                        });
                    }
                } catch (error) { }
                return tableNames;
            }
        },
        sqlString() {
            let sql = "";
            this.allTableData.forEach((item, index) => {
                if (index == 0) {
                    sql = (this.form.Distinct == '0' ? "SELECT " : "SELECT DISTINCT ");
                    if (item.TABLE_NAME == this.tableName) {
                        sql = sql + item.TABLE_NAME + ".`" + item.COLUMN_NAME + "`"
                    } else {
                        sql = sql + "IFNULL(" + item.TABLE_NAME + ".`" + item.COLUMN_NAME + "`"
                    }
                } else {
                    if (item.TABLE_NAME == this.tableName) {
                        sql = sql + ",\r\n" + item.TABLE_NAME + ".`" + item.COLUMN_NAME + "`";
                    } else {
                        sql = sql + ",\r\nIFNULL(" + item.TABLE_NAME + ".`" + item.COLUMN_NAME + "`";
                    }
                }
                //判断是否有指定名称
                if (item.TABLE_NAME == this.tableName) {
                    if (item.NickName) {
                        sql = sql + " As " + "`" + item.NickName + "`"
                    }
                } else {
                    if (item.NickName) {
                        sql = sql + ",'') As " + "`" + item.NickName + "`"
                    } else {
                        sql = sql + ",'')"
                    }
                }
            })
            if (sql) {
                sql = sql + "\r\nFROM " + this.tableName;
                this.lineList.forEach(item => {
                    sql = sql + "\r\n" + item.Join + " " + item.targetId + " ON " + item.sourceUuid.slice(0, -2) + " = " + item.targetUuid.slice(0, -2)
                })
            }
            let condition = this.condition.filter(i => (i.COLUMN_NAME && i.Logic) || i.Logic == '{?}');
            if (condition.length > 0) {
                condition.forEach((item, index) => {
                    if (index) {
                        if (item.Logic == '{?}') {
                            sql += "\r\n{?}"
                        } else if (item.Logic.includes("LIKE")) {
                            sql += "\r\nAND " + item.COLUMN_NAME + " " + item.Logic + (item.Value == '?' ? " " + item.Value : " '%" + item.Value + "%'");
                        } else {
                            sql += "\r\nAND " + item.COLUMN_NAME + " " + item.Logic + (item.Value == '?' ? " " + item.Value : " '" + item.Value + "'");
                        }
                    } else {
                        if (item.Logic == '{?}') {
                            sql += "\r\n{?}"
                        } else if (item.Logic.includes("LIKE")) {
                            sql += "\r\nWHERE " + item.COLUMN_NAME + " " + item.Logic + (item.Value == '?' ? " " + item.Value : " '%" + item.Value + "%'");
                        } else {
                            sql += "\r\nWHERE " + item.COLUMN_NAME + " " + item.Logic + (item.Value == '?' ? " " + item.Value : " '" + item.Value + "'");
                        }
                    }
                })
            }
            let order = this.order.filter(i => i.COLUMN_NAME);
            if (order.length > 0) {
                order.forEach((item, index) => {
                    if (index) {
                        sql += ",\r\n" + item.COLUMN_NAME + " " + item.Mode;
                    } else {
                        sql += "\r\nORDER BY " + item.COLUMN_NAME + " " + item.Mode;
                    }
                })
            }
            return sql;
        }
    },
    watch: {
        tableName(Data, oldData) {
            const that = this;
            httpRequest({
                hostApi: BASE_URL1,
                url: `/generalQueryAllColumnByTableName?TableName=${Data}`,
                type: 'GET',
            }).then(res => {
                if (res.Status == 'success' && res.Data.length > 0) {
                    res.Data.forEach(item => {
                        item.NickName = item.COLUMN_NAME;
                        item.Column_Width = '180';
                        item.Column_Type = '0';
                        item.Show_Overflow_Tooltip = true;
                        item.Column_Align = 'left';
                        item.Role = '';
                        item.isShow = true;
                    })
                    that.tableData = res.Data;
                    that.$nextTick(() => {
                        that.jsPlumbInstance.batch(() => {// 批量执行并重新渲染
                            if (oldData) {//删除旧锚点
                                that.jsPlumbInstance.getEndpoints(oldData).forEach(endpoint => {
                                    that.jsPlumbInstance.deleteEndpoint(endpoint);
                                })
                                //当锚点删除时，上面的连接线自动删除，此时可以通过删除连接线监听事件处理
                            }
                            res.Data.forEach((obj, index) => {
                                that.jsPlumbInstance.addEndpoint(Data, {
                                    anchor: [0, accAdd(accDiv(index + 1, res.Data.length + 1), accDiv(1, res.Data.length + 1) / 2), 0, 0],
                                    uuid: Data + '.' + Data.COLUMN_NAME + '-0'
                                }, that.commonLink)
                                that.jsPlumbInstance.addEndpoint(Data, {
                                    anchor: [1, accAdd(accDiv(index + 1, res.Data.length + 1), accDiv(1, res.Data.length + 1) / 2), 0, 0],
                                    uuid: Data + '.' + obj.COLUMN_NAME + '-1'
                                }, that.commonLink);
                            })
                            that.jsPlumbInstance.draggable(Data);
                        })
                        if (that.actualNumber < that.tableNumber) {
                            that.actualNumber++;
                        }
                    })
                }
            }).catch(xhr => {
                this.$message({
                    message: '系统错误，请联系开发者!',
                    type: 'error'
                })
            });
        },
        selecteTable(Data) {
            const that = this;
            Data.forEach(item => {
                if (!this.subTable.some(i => i.tableName == item)) {//新的添加表
                    httpRequest({
                        hostApi: BASE_URL1,
                        url: `/generalQueryAllColumnByTableName?TableName=${item}`,
                        type: 'GET',
                    }).then(res => {
                        if (res.Status == 'success') {
                            res.Data.forEach(item => {
                                item.NickName = item.COLUMN_NAME;
                                item.Column_Width = '180';
                                item.Column_Type = '0';
                                item.Show_Overflow_Tooltip = true;
                                item.Column_Align = 'left';
                                item.Role = '';
                                item.isShow = true;
                            })
                            that.subTable.push({
                                tableName: item,
                                top: 0,
                                left: 0,
                                tableData: res.Data
                            });
                            that.$nextTick(() => {
                                that.jsPlumbInstance.batch(() => {// 批量执行并重新渲染
                                    // 添加锚点
                                    res.Data.forEach((obj, index) => {
                                        that.jsPlumbInstance.addEndpoint(item, {
                                            anchor: [0, accAdd(accDiv(index + 1, res.Data.length + 1), accDiv(1, res.Data.length + 1) / 2), 0, 0],
                                            uuid: item + '.' + obj.COLUMN_NAME + '-0'
                                        }, that.commonLink)
                                        that.jsPlumbInstance.addEndpoint(item, {
                                            anchor: [1, accAdd(accDiv(index + 1, res.Data.length + 1), accDiv(1, res.Data.length + 1) / 2), 0, 0],
                                            uuid: item + '.' + obj.COLUMN_NAME + '-1'
                                        }, that.commonLink)
                                    })
                                    // 添加拖拽
                                    that.jsPlumbInstance.draggable(item);
                                })
                                // that.jsPlumbInstance.repaintEverything(); // 重新渲染
                                if (that.actualNumber < that.tableNumber) {
                                    that.actualNumber++;
                                }
                            })
                        }
                    }).catch(xhr => {
                        this.$message({
                            message: '系统错误，请联系开发者!',
                            type: 'error'
                        })
                    })
                }
            })
            //删除旧锚点
            const oldData = this.subTable.filter(i => !Data.some(tableName => tableName == i.tableName))[0];
            if (oldData) {
                that.jsPlumbInstance.batch(() => {// 批量执行并重新渲染
                    const { tableName } = oldData;
                    that.jsPlumbInstance.getEndpoints(tableName).forEach(endpoint => {
                        let allConnections = that.jsPlumbInstance.getAllConnections();//所有线条
                        allConnections.filter(connection => {//当前相关线条
                            return connection.source === endpoint.element || connection.target === endpoint.element;
                        }).forEach(connection => {
                            this.jsPlumbInstance.deleteConnection(connection);//删除线条
                        });
                        that.jsPlumbInstance.deleteEndpoint(endpoint);//删除锚点
                    })
                })
            }
            //筛掉取消的表
            this.subTable = this.subTable.filter(i => Data.some(tableName => tableName == i.tableName));
            that.jsPlumbInstance.repaintEverything();
        },
        tableNames(val) {
            if (this.action != 'Modify') {// || !this.isModify
                this.allTableData = val;
            }
        },
        isSort(val) {
            this.Sortable.option('disabled', !val);
        },
        actualNumber(val) {//等待画布中的所有数据表渲染完成后再连线，不然会报错
            if (this.action == 'Modify' && this.tableNumber != 0 && this.tableNumber == val) {
                this.form.Line_JSON.forEach(item => {
                    this.jsPlumbInstance.connect({
                        uuids: [item.sourceUuid, item.targetUuid],
                    });
                })
                this.jsPlumbInstance.repaintEverything(); // 重新渲染
                this.getAllTableData();
                this.$nextTick(() => {
                    this.isModify = !this.isModify;
                })
            }
        }
    },
    mounted() {//初始化
        let ls_URL = window.location.href;
        this.action = getQueryObject(ls_URL, "action");// 获取 nodeKey 参数
        this.nodeKey = getQueryObject(ls_URL, "nodeKey"); // 获取 action 参数
        this.referrer = document.referrer;
        let Model_Url = sessionStorage.getItem("Url")
        if (Model_Url) {
            this.form.Model_Url = Model_Url;
        }
        this.getInfo();
        this.getData();
        this.$nextTick(() => { //拖拽排序
            var $ul = this.$el.querySelector('#table tbody')
            $ul.addEventListener('selectstart', function (e) {
                e.preventDefault();
            })
            this.Sortable = Sortable.create($ul, {
                handle: '.el-table__row',
                draggable: '.el-table__row',
                animation: 150,
                onUpdate: (event) => {
                    let newIndex = event.newIndex, oldIndex = event.oldIndex;
                    $li = $ul.children[newIndex], $oldLi = $ul.children[oldIndex]
                    //先删除移动的节点, 再插入移动的节点到原有节点，还原了移动的操作
                    $ul.removeChild($li)
                    if (newIndex > oldIndex) {
                        $ul.insertBefore($li, $oldLi)
                    } else {
                        $ul.insertBefore($li, $oldLi.nextSibling)
                    }
                    //通过改变vue遍历数组移动节点
                    let item = this.allTableData[oldIndex];
                    this.allTableData.splice(oldIndex, 1);
                    this.allTableData.splice(newIndex, 0, item);
                }
            })
            this.Sortable.option('disabled', true);
        })
        window.addEventListener('resize', () => {
            this.jsPlumbInstance.repaintEverything();
        });
    },
    methods: {
        configTable(tableName) {//链表后获取可查询字段
            let Data = []
            this.lineList.filter(i => i.sourceId == tableName).forEach(item => {
                let Data1;
                try {
                    Data1 = this.subTable.filter(i => i.tableName == item.targetId)[0].tableData;
                } catch (error) {
                    Data1 = [];
                }
                let Data2 = this.configTable(item.targetId)
                Data = [...Data, ...Data1, ...Data2];
            })
            return Data;
        },
        getData() {//初始化查询全部表，修改查询已有数据
            const that = this;
            generalApi.generalFilePath('role.json').then(data => {
                this.role = [{ label: '不关联权限', value: '' }, ...data.filter(i => i.type == 'text')];
            }).catch(xhr => {
                this.$message({
                    message: '系统错误，请联系开发者!',
                    type: 'error'
                })
            });
            httpRequest({
                hostApi: BASE_URL1,
                url: '/generalQueryAllTableName',
                type: 'GET',
            }).then(res => {
                if (res.Status == 'success') {
                    that.table = res.Data;
                }
            }).catch(xhr => {
                this.$message({
                    message: '系统错误，请联系开发者!',
                    type: 'error'
                })
            });
            if (this.action == 'Modify') {//修改
                httpRequest({
                    hostApi: BASE_URL1,
                    url: '/generalQueryByTableNames',
                    data: {
                        Data: JSON.stringify({
                            base_sql_list: {
                                Condition: `SQL_SerialNumber='${this.nodeKey}'`,
                                Original: '1'
                            },
                            base_sql_table_config: {
                                Condition: `SQL_SerialNumber='${this.nodeKey}'`,
                                Original: '1'
                            }
                        })
                    }
                }).then(res => {
                    if (res.Status == 'success') {
                        const { base_sql_list, base_sql_table_config } = res.Data;
                        if (base_sql_list.length == 1) {
                            // base_sql_list[0].Box_JSON = base_sql_list[0].Box_JSON;
                            base_sql_list[0].Box_JSON_Original = JSON.stringify(base_sql_list[0].Box_JSON_Original);
                            // base_sql_list[0].Condition = base_sql_list[0].Condition;
                            base_sql_list[0].Condition_Original = JSON.stringify(base_sql_list[0].Condition_Original);
                            // base_sql_list[0].Line_JSON = base_sql_list[0].Line_JSON;
                            base_sql_list[0].Line_JSON_Original = JSON.stringify(base_sql_list[0].Line_JSON_Original);
                            // base_sql_list[0].Order = base_sql_list[0].Order;
                            base_sql_list[0].Order_Original = JSON.stringify(base_sql_list[0].Order_Original);
                            let SQL_Type = base_sql_list[0].SQL_Type, selecteTable = [];
                            base_sql_list[0].Children = { base_sql_table_config };
                            if (SQL_Type == '0') {
                                this.isTabs = false;
                                if (base_sql_table_config.length >= 1) {
                                    this.tableName = base_sql_table_config.filter(i => i.Table_Type == '0' && i.Row_Status != '1')[0].Table_Name;
                                    base_sql_table_config.filter(i => i.Table_Type == '1' && i.Row_Status != '1').forEach(item => {
                                        if (!selecteTable.some(i => i == item.Table_Name)) {
                                            selecteTable.push(item.Table_Name);
                                        }
                                    })
                                }
                            }
                            this.tableNumber = 1 + selecteTable.length;
                            this.form = base_sql_list[0];
                            this.Box_JSON = base_sql_list[0].Box_JSON;
                            this.selecteTable = selecteTable;
                            this.condition = base_sql_list[0].Condition;
                            this.order = base_sql_list[0].Order;
                            if (SQL_Type == '1') {
                                this.SQL = deutf8ToBase64(base_sql_list[0].SQL_Statement);
                                this.getAllTableData();
                            }
                        }
                    }
                }).catch(xhr => {
                    this.$message({
                        message: '系统错误，请联系开发者!',
                        type: 'error'
                    })
                });
            }
        },
        getInfo() {//拖拽初始化
            this.$nextTick().then(() => {
                jsPlumb.ready(() => {
                    // 创建jsPlumb实例
                    this.jsPlumbInstance = jsPlumb.getInstance();
                    // 导入准备好的jsPlumb配置
                    this.jsPlumbInstance.importDefaults(this.jsPlumbSetting);
                    //连线前监听，阻止一些不允许的连线
                    this.jsPlumbInstance.bind('beforeDrop', (event) => {
                        if (event.sourceId == event.targetId) { //当与自己表连线时，阻止连线
                            return false
                        } else if (event.targetId == this.tableName) {//被连线的是主表时，取消连线
                            this.$message({
                                message: '被连接的表不能为主表',
                                type: 'warning'
                            });
                            return false
                        } else if (event.sourceId != this.tableName && !this.lineList.some(i => i.targetId == event.sourceId)) {//若连接表不为主表，则该表需要校验连接表是否跟主表有关系才能进行连接
                            this.$message({
                                message: '当前表暂未与主表关联，无法连接其它表',
                                type: 'warning'
                            });
                            return false
                        }
                        return true // 链接会自动建立
                    })
                    // 监听连线事件
                    this.jsPlumbInstance.bind('connection', (event) => {
                        const Join = "LEFT JOIN";
                        //在连接线上添加文字
                        var labelOverlay = ["Label", {
                            label: this.Join.filter(i => i.value == Join)[0].label, // 要显示的文字  
                            location: 0.5, // 文字在连接线上的位置（0 到 1 之间的值）
                            cssClass: "connection-label",// 可选的 CSS 类名，用于自定义样式
                            id: "labelOverlay" + event.connection.id
                        }];
                        this.lineList.push({
                            sourceId: event.sourceId,
                            targetId: event.targetId,
                            sourceUuid: event.connection.endpoints[0].getUuid(),
                            targetUuid: event.connection.endpoints[1].getUuid(),
                            Join,
                            connection: event.connection
                        })
                        event.connection.addOverlay(labelOverlay);
                    });
                    // 监听删除连线事件
                    this.jsPlumbInstance.bind('connectionDetached', ({ connection }) => {
                        const sourceUuid = connection.endpoints[0].getUuid();
                        const targetUuid = connection.endpoints[1].getUuid();
                        const sourceId = sourceUuid.split('.')[0];
                        const targetId = targetUuid.split('.')[0];
                        this.lineList = this.lineList.filter(i => i.sourceUuid != sourceUuid && i.targetUuid != targetUuid);
                        this.removeLine(targetId, sourceId);
                    });
                    // 点击连接事件
                    this.jsPlumbInstance.bind('click', (connection) => {
                        let sourceUuid = connection.endpoints[0].getUuid();
                        let targetUuid = connection.endpoints[1].getUuid();
                        this.selectLine = this.lineList.filter(i => i.sourceUuid == sourceUuid && i.targetUuid == targetUuid)[0];
                        this.selectLine.Join_Original = this.selectLine.Join;
                        this.dialogVisible = true;
                    });
                })
            })
        },
        getAllTableData() {
            this.allTableData = [], base_sql_table_config = this.form.Children.base_sql_table_config.filter(i => i.Row_Status != '1');
            base_sql_table_config.sort((a, b) => a.Sort - b.Sort);
            base_sql_table_config.forEach(item => {
                this.allTableData.push({
                    TABLE_NAME: item.Table_Name,
                    COLUMN_NAME: item.Column_Name,
                    NickName: item.NickName,
                    COLUMN_COMMENT: item.Column_Comment,
                    isShow: item.Show == '1' ? false : true,
                    Column_Width: item.Column_Width,
                    Column_Type: item.Column_Type,
                    Show_Overflow_Tooltip: item.Show_Overflow_Tooltip == '1' ? false : true,
                    Column_Align: item.Column_Align,
                    Role: item.Role,
                })
            })
        },
        cancel() { //取消
            this.dialogVisible = false;
            this.selectLine.Join = this.selectLine.Join_Original;
        },
        submitSave() {//保存
            if (this.selectLine.Join != this.selectLine.Join_Original) {
                this.lineList.filter(i => i.targetId == this.selectLine.targetId).forEach(item => {
                    const overlays = item.connection.getOverlays();
                    //获取文字对象
                    for (let key in overlays) {
                        if (key.startsWith("labelOverlay")) {
                            //移除旧的overlays，
                            item.connection.removeOverlays(key);
                        }
                    }
                    //添加新的
                    item.connection.addOverlay(["Label", {
                        label: this.Join.filter(i => i.value == this.selectLine.Join)[0].label, // 要显示的文字  
                        location: 0.5, // 文字在连接线上的位置（0 到 1 之间的值）
                        cssClass: "connection-label",// 可选的 CSS 类名，用于自定义样式
                        id: "labelOverlay" + item.connection.id
                    }])
                })
            }
            this.dialogVisible = false;
        },
        removeLine(targetId, sourceId) {//删除线条，递归
            if (!this.lineList.some(i => i.targetId == targetId && i.sourceId != sourceId)) {
                this.lineList.filter(i => i.sourceId == targetId).forEach(item => {
                    this.jsPlumbInstance.deleteConnection(item.connection);
                    this.removeLine(item.targetId, item.sourceId);
                })
                this.lineList = this.lineList.filter(i => i.sourceId != targetId);
            }
        },
        removeSave() {//删除连接线
            this.$confirm('确定删除此连线吗, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                const { sourceUuid, targetUuid, sourceId, targetId, connection } = this.selectLine;
                this.jsPlumbInstance.deleteConnection(connection);
                //以下代码移动到连接线监听事件中
                // this.lineList = this.lineList.filter(i => i.sourceUuid != sourceUuid && i.targetUuid != targetUuid);
                // this.removeLine(targetId, sourceId)//判断被连表有无其它被连接线条，没有删除该表发起的所以线条
                this.selectLine = {};
                this.dialogVisible = false;
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                });
            }).catch(() => { });
        },
        removeTable(row, index) {//删除一条待查寻数据
            const num = this.allTableData.reduce((count, current) => {
                return current.TABLE_NAME === this.allTableData[index].TABLE_NAME ? count + 1 : count;
            }, 0);
            if (this.isfirst) {
                this.$confirm('(仅首次操作提示)该操作将移除此字段,sql中将无法查询该字段,是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning',
                }).then(() => {
                    if (num > 1 || !this.lineList.some(i => i.targetId == row.TABLE_NAME || i.sourceId == row.TABLE_NAME)) {
                        this.allTableData = this.allTableData.filter((it, id) => id != index);
                    } else {
                        this.$message({
                            message: '不能在移除了，至少保留一个该表(' + this.allTableData[index].TABLE_NAME + ')的字段',
                            type: 'warning'
                        })
                    }
                    this.isfirst = false;
                }).catch(() => { this.isfirst = false; });
            } else {
                if (num > 1 || !this.lineList.some(i => i.targetId == row.TABLE_NAME || i.sourceId == row.TABLE_NAME)) {
                    this.allTableData = this.allTableData.filter((it, id) => id != index);
                } else {
                    this.$message({
                        message: '不能在移除了，至少保留一个该表(' + this.allTableData[index].TABLE_NAME + ')的字段',
                        type: 'warning'
                    })
                }
            }
        },
        handleDistinct() {//去重处理
            console.log(this.form.Distinct);
            if (this.form.Distinct == '0') {
                this.form.Distinct = '1';
            } else {
                this.form.Distinct = '0';
            }
        },
        add_condition() {//添加条件
            this.condition.push({
                COLUMN_NAME: '',
                Logic: '',
                Value: '',
            })
        },
        remove_condition() {//删除条件
            if (this.condition.length > 0) {
                this.condition.pop();
            } else {
                this.$message({
                    message: '不能在删除了',
                    type: 'warning'
                })
            }
        },
        add_order() {//添加排序方式
            this.order.push({
                COLUMN_NAME: '',
                Mode: '',
            })
        },
        remove_order() {//删除排序方式
            if (this.order.length > 0) {
                this.order.pop();
            } else {
                this.$message({
                    message: '不能在删除了',
                    type: 'warning'
                })
            }
        },
        rowStyle({ row }) {//拖拽式改变表格颜色
            if (this.isSort) {
                return { backgroundColor: '#f0f9eb' };
            }
            return {}

        },
        async validateAllForms() {
            //获取当前页面上所有的Elform
            let forms = [];
            for (let key in this.$refs) {
                const ref = this.$refs[key];
                if (ref.$options && ref.$options.name == 'ElForm') {
                    forms.push(ref);
                }
            }
            //判断每个Elform的校验是否通过
            let isfail = false;
            for (const form of forms) {
                try {
                    await form.validate();
                } catch (error) {
                    isfail = true;
                }
            }
            if (isfail) {
                return false;
            }
            return true;
        },
        async submitForm() {//点击提交按钮时提交
            const allValid = await this.validateAllForms();
            if (allValid) {
                const that = this;
                this.loading = true;
                let arr = [];
                this.lineList.forEach(item => {
                    arr.push({
                        sourceId: item.sourceId,
                        targetId: item.targetId,
                        sourceUuid: item.sourceUuid,
                        targetUuid: item.targetUuid,
                        Join: item.Join,
                    });
                })
                const tableName = [this.tableName, ...this.selecteTable];
                let Box_JSON = new Object();
                if (this.form.SQL_Type == '0') {//组合SQL
                    this.form.SQL_Statement = utf8ToBase64(this.sqlString);
                    tableName.forEach(item => {
                        const { offsetTop, offsetLeft } = document.querySelector('#' + item);
                        Box_JSON[item] = { top: offsetTop, left: offsetLeft }
                    })
                } else if (this.form.SQL_Type == '1') {//自定义SQL
                    this.form.SQL_Statement = utf8ToBase64(this.SQL);
                }
                this.form.Condition = JSON.stringify(this.condition.filter(i => (i.COLUMN_NAME && i.Logic) || i.Logic == '{?}'));
                this.form.Order = JSON.stringify(this.order.filter(i => i.COLUMN_NAME));
                this.form.Line_JSON = JSON.stringify(arr);
                this.form.Box_JSON = JSON.stringify(Box_JSON);
                let JSONObject_Data = new Object();
                if (this.action == 'Add') {
                    let base_sql_table_config = [];
                    this.allTableData.forEach((item, index) => {
                        base_sql_table_config.push({
                            SQL_Model_List_SerialNumber: '',
                            SQL_SerialNumber: this.form.SQL_SerialNumber,
                            Table_Name: item.TABLE_NAME,
                            Table_Type: this.tableName == item.TABLE_NAME ? '0' : '1',
                            Column_Name: item.COLUMN_NAME,
                            NickName: item.NickName,
                            Column_Comment: item.COLUMN_COMMENT,
                            Show: item.isShow ? '0' : '1',
                            Sort: index + 1,
                            Column_Width: item.Column_Width,
                            Column_Type: item.Column_Type,
                            Show_Overflow_Tooltip: item.Show_Overflow_Tooltip ? '0' : '1',
                            Column_Align: item.Column_Align,
                            Role: item.Role
                        })
                    })
                    JSONObject_Data = { Add: { base_sql_list: [this.form], base_sql_table_config } }
                } else if (this.action == 'Modify') {
                    this.allTableData.forEach((item, index) => {
                        let obj = this.form.Children.base_sql_table_config.filter(i => i.Table_Name == item.TABLE_NAME && i.Column_Name == item.COLUMN_NAME)[0];
                        if (obj) {//修改
                            obj.Table_Type = (this.tableName == item.TABLE_NAME ? '0' : '1');
                            obj.NickName = item.NickName;
                            obj.Column_Comment = item.COLUMN_COMMENT;
                            obj.Show = item.isShow ? '0' : '1';
                            obj.Sort = index + 1;
                            obj.Column_Width = item.Column_Width;
                            obj.Column_Type = item.Column_Type;
                            obj.Show_Overflow_Tooltip = item.Show_Overflow_Tooltip ? '0' : '1';
                            obj.Column_Align = item.Column_Align;
                            obj.Role = item.Role;
                            obj.Row_Status = '0';
                        } else {//新增
                            this.form.Children.base_sql_table_config.push({
                                SQL_Model_List_SerialNumber: '',
                                SQL_SerialNumber: this.form.SQL_SerialNumber,
                                Table_Name: item.TABLE_NAME,
                                Table_Type: this.tableName == item.TABLE_NAME ? '0' : '1',
                                Column_Name: item.COLUMN_NAME,
                                NickName: item.NickName,
                                Column_Comment: item.COLUMN_COMMENT,
                                Show: item.isShow ? '0' : '1',
                                Sort: index + 1,
                                Column_Width: item.Column_Width,
                                Column_Type: item.Column_Type,
                                Show_Overflow_Tooltip: item.Show_Overflow_Tooltip ? '0' : '1',
                                Column_Align: item.Column_Align,
                                Role: item.Role
                            })
                        }
                    })
                    //移除的字段做删除处理
                    this.form.Children.base_sql_table_config.forEach(item => {
                        if (!this.allTableData.some(i => i.TABLE_NAME == item.Table_Name && i.COLUMN_NAME == item.Column_Name)) {
                            item.Row_Status = '1';
                        }
                    })
                    this.form.Children.base_sql_table_config.forEach(item => {
                        item.SQL_SerialNumber = this.form.SQL_SerialNumber;
                    })
                    const { add, modify } = this.deal(this.form);
                    let base_sql_table_config = modify.Children.base_sql_table_config;
                    delete modify.Children;
                    let modify_base_sql_list = modify;
                    JSONObject_Data = { Modify: { base_sql_list: [modify_base_sql_list], base_sql_table_config } }
                    if (add != null) {
                        let base_sql_table_config = add.Children.base_sql_table_config;
                        JSONObject_Data['Add'] = { base_sql_table_config };
                    }
                }
                let Operation_Main = JSON.stringify(deepClone(JSONObject_Data));
                if (!JSONObject_Data['Add']) {
                    JSONObject_Data['Add'] = new Object();
                }
                JSONObject_Data['Add']['base_operation_log'] = [{
                    Operation_Type: '0',
                    Operation_Path: getRelativePath(),
                    Operation_Description: (this.action == 'Add' ? '添加SQL配置数据' : '修改SQL配置数据'),
                    Operation_Main,
                    Operation_Interface: "generalSaveByRequestBody",
                    Operation_IP: getIpAddress()
                }]

                httpRequest({
                    contentType: 'JSON',
                    url: '/generalBusiness/generalSaveByRequestBody',
                    data: JSON.stringify({
                        Data: JSONObject_Data
                    })
                }).then(res => {
                    if (res.Status === 'success') {
                        that.$message.success("提交成功")
                        if (this.referrer) {
                            window.location.href = this.referrer; // 返回上一页
                        } else {
                            window.history.back(); // 尝试后退（兼容直接访问的情况）
                        }
                    } else {
                        that.$message.error("提交失败，请稍后再试")
                    }
                }).catch(xhr => {
                    this.$message.error("系统错误，请联系开发者!")
                }).finally(() => {
                    this.loading = false;
                })
            } else {
                this.$message({
                    message: '存在未填写的必填项！',
                    type: 'warning'
                });
            }
        },
        deal(form) {    //将待提交的数据中添加和修改分离出来
            const add = deepClone(form), modify = deepClone(form);
            try {
                for (let key in form.Children) {
                    let add_Data = [], modify_Data = [];
                    for (const i in modify.Children[key]) {
                        const obj = modify.Children[key][i];
                        if (!Object.keys(obj).some(item => item.includes('_Original'))) {
                            add_Data.push(obj);
                        } else {
                            modify_Data.push(obj);
                        }
                    }
                    add.Children[key] = add_Data;
                    modify.Children[key] = modify_Data;
                }
                let lb_is = true;
                for (let key in add.Children) {
                    if (add.Children[key].length > 0) {
                        lb_is = false;
                    }
                }
                if (lb_is) {
                    return { add: null, modify };
                }
                return { add, modify };
            } catch (error) {
                return { add: null, modify };
            }
        },
        beforeTabLeave() {
            if (this.action == 'Modify') {
                if (this.isTabs) {
                    this.isTabs = false;
                } else {
                    this.$confirm('该操作将会切换该SQL配置类型，并刷新当前页面，是否继续!', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                    }).then(() => {
                        httpRequest({
                            hostApi: BASE_URL1,
                            url: '/generalQueryByTableName',
                            data: {
                                TableName: 'base_sql_list',
                                Condition: `SQL_SerialNumber='${this.form.SQL_SerialNumber}'`,
                                Original: '1'
                            }
                        }).then(res => {
                            if (res.Status == 'success') {
                                const base_sql_list = res.Data;
                                base_sql_list[0].SQL_Type = this.form.SQL_Type == '0' ? '1' : '0';
                                let JSONObject_Data = {
                                    Modify: { base_sql_list }
                                };
                                let Operation_Main = JSON.stringify(deepClone(JSONObject_Data));
                                if (!JSONObject_Data['Add']) {
                                    JSONObject_Data['Add'] = new Object();
                                }
                                JSONObject_Data['Add']['base_operation_log'] = [{
                                    Operation_Type: '0',
                                    Operation_Path: getRelativePath(),
                                    Operation_Description: '切换SQL配置类型数据',
                                    Operation_Main,
                                    Operation_Interface: "generalSave",
                                    Operation_IP: getIpAddress()
                                }]

                                httpRequest({
                                    hostApi: BASE_URL1,
                                    url: `/generalSave`,
                                    type: 'POST',
                                    data: {
                                        Data: JSON.stringify(JSONObject_Data)
                                    }
                                }).then(res => {
                                    if (res.Status === 'success') {
                                        window.location.reload();
                                    }
                                }).catch(xhr => {
                                    this.$message({
                                        message: '系统错误，请联系开发者!',
                                        type: 'error'
                                    })
                                });

                            }
                        }).catch(xhr => {
                            this.$message({
                                message: '系统错误，请联系开发者!',
                                type: 'error'
                            })
                        })
                    }).catch(() => { });
                    return false;
                }
            }
        },
        handleClick() {
            if (this.action == 'Add') {
                this.reset();
            }
        },
        reset() {//初始化当前页面
            this.jsPlumbInstance.reset();//
            this.getInfo();//初始化
            this.tableName = '', this.selecteTable = [], this.allTableData = [], this.lineList = [], this.subTable = [], this.tableData = [], this.condition = [], this.SQL = '';
        },
        submitRecycle() {//确认添加字段
            this.recycle.forEach(item => {
                let arr = item.split('.');
                let obj = this.tableNames.filter(i => i.TABLE_NAME == arr[0] && i.COLUMN_NAME == arr[1])[0];
                if (obj) {
                    this.allTableData.push(obj);
                }
            })
            this.$message.success("添加成功");
            this.cancelRecycle();
        },
        cancelRecycle() {//取消当前回收站选中字段
            this.recycle = [];
            this.dialogVisible2 = false;
        },
    }
})